package com.kaplan.hackathon.search.service;

import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.LinkedInApi;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import com.kaplan.hackathon.search.model.Jobs;

public class SearchLinkedInJobsService {

	static OAuthService oAuthService;
	private static String CONSUMER_KEY_VALUE = "s9ji8i09qbo4";
	private static String CONSUMER_SECRET_VALUE = "cVNcnDZMzF4hww80";
	private static String ACCESS_TOKEN = "4eafe755-3cd6-4e86-a325-2d27d764cd6f";
	private static String TOKEN_SECRET = "069a98d7-016f-456d-acc5-5687abb4d9f8";
	static String totalCount;

	public static ArrayList<Jobs> searchKeywords(String keywords,
			String startCount, String totalCount)
			throws UnsupportedEncodingException, XMLStreamException {
		// JobSearchLinkedInConstants.loadProperties();
		// System.out.println(JobSearchLinkedInConstants.CONSUMER_KEY_VALUE);
		oAuthService = new ServiceBuilder().provider(LinkedInApi.class)
				.apiKey(CONSUMER_KEY_VALUE).apiSecret(CONSUMER_SECRET_VALUE)
				.build();
		keywords = keywords.replaceAll(" ", "%20");
		String url = "http://api.linkedin.com/v1/job-search?keywords="
				+ keywords + "&start=" + startCount + "&count=" + totalCount;
		OAuthRequest oAuthRequest = new OAuthRequest(Verb.GET, url);
		oAuthService.signRequest(new Token(ACCESS_TOKEN, TOKEN_SECRET),
				oAuthRequest);
		Response response = oAuthRequest.send();
		String content = response.getBody();
		ArrayList<Jobs> jobsList = createJobList(content);
		return jobsList;
	}

	public static String searchJOB(String jobId)
			throws UnsupportedEncodingException, XMLStreamException {
		// JobSearchLinkedInConstants.loadProperties();
		// System.out.println(JobSearchLinkedInConstants.CONSUMER_KEY_VALUE);
		oAuthService = new ServiceBuilder().provider(LinkedInApi.class)
				.apiKey(CONSUMER_KEY_VALUE).apiSecret(CONSUMER_SECRET_VALUE)
				.build();
		// keywords = keywords.replaceAll(" ", "%20");
		// String url =
		// "http://api.linkedin.com/v1/job-search?keywords="+keywords+"&start="+startCount+"&count="+totalCount;
		String url = "http://api.linkedin.com/v1/jobs/6597429:(id,posting-timestamp,company:(name),position:(title,location,job-functions),skills-and-experience,description,site-job-url,description-snippet)";
		OAuthRequest oAuthRequest = new OAuthRequest(Verb.GET, url);
		oAuthService.signRequest(new Token(ACCESS_TOKEN, TOKEN_SECRET),
				oAuthRequest);
		Response response = oAuthRequest.send();
		String content = response.getBody();
		return content;
	}

	public static ArrayList<Jobs> createJobList(String content)
			throws XMLStreamException, UnsupportedEncodingException {

		byte[] byteArray = content.getBytes("UTF-8");
		ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArray);
		XMLInputFactory inputFactory = XMLInputFactory.newInstance();
		XMLEventReader eventReader = inputFactory
				.createXMLEventReader(inputStream);

		Jobs jobs = null;

		ArrayList<Jobs> jobList = new ArrayList<Jobs>();

		boolean flag = false;
		try{
			while (eventReader.hasNext()) {
	
				XMLEvent event = eventReader.nextEvent();
	
				if (event.isStartElement()) {
	
					StartElement startElement = event.asStartElement();
	
					if (startElement.getName().getLocalPart() == ("jobs")) {
	
						Iterator<Attribute> attributes = startElement
								.getAttributes();
						while (attributes.hasNext()) {
							Attribute attribute = attributes.next();
							if (attribute.getName().toString().equals("total")) {
								totalCount = attribute.getValue();
							}
	
						}
	
					}
	
					if (startElement.getName().getLocalPart() == ("job")) {
	
						jobs = new Jobs();
	
						flag = true;
	
					}
	
					if (event.isStartElement()) {
						if (event.asStartElement().getName().getLocalPart()
								.equals("id")
								&& flag) {
	
							event = eventReader.nextEvent();
	
							jobs.setId(event.asCharacters().getData());
	
							flag = false;
							continue;
	
						}
	
					}
	
					if (event.isStartElement()) {
						if (event.asStartElement().getName().getLocalPart()
								.equals("name")) {
	
							event = eventReader.nextEvent();
	
							jobs.setCompanyName(event.asCharacters().getData());
							continue;
	
						}
	
					}
	
					if (event.isStartElement()) {
						if (event.asStartElement().getName().getLocalPart()
								.equals("first-name")) {
	
							event = eventReader.nextEvent();
	
							jobs.setPostedByFirstName(event.asCharacters()
									.getData());
							continue;
	
						}
	
					}
	
					if (event.isStartElement()) {
						if (event.asStartElement().getName().getLocalPart()
								.equals("last-name")) {
	
							event = eventReader.nextEvent();
	
							jobs.setPostedByLastName(event.asCharacters().getData());
							continue;
	
						}
	
					}
	
					if (event.isStartElement()) {
						if (event.asStartElement().getName().getLocalPart()
								.equals("headline")) {
	
							event = eventReader.nextEvent();
	
							jobs.setHeadLine(event.asCharacters().getData());
							continue;
	
						}
	
					}
	
					if (event.isStartElement()) {
						if (event.asStartElement().getName().getLocalPart()
								.equals("description-snippet")) {
	
							event = eventReader.nextEvent();
	
							jobs.setDescriptionSnippet(event.asCharacters()
									.getData());
							continue;
	
						}
	
					}
	
					if (event.isStartElement()) {
						if (event.asStartElement().getName().getLocalPart()
								.equals("location-description")) {
	
							event = eventReader.nextEvent();
	
							jobs.setLocationDescription(event.asCharacters()
									.getData());
							continue;
	
						}
	
					}
	
				}
	
				if (event.isEndElement()) {
					EndElement endElement = event.asEndElement();
					if (endElement.getName().getLocalPart() == ("job")) {
						jobList.add(jobs);
					}
				}
	
			}
		}catch(Exception e){
			jobList = new ArrayList<Jobs>();
		}

		return jobList;

	}

	public static void displayJobs(List<Jobs> jobList) {

		System.out.println(" Total jobs from the keyword search " + totalCount);

		for (Jobs job : jobList) {

			System.out.println(" Job Id "
					+ (job.getId() != null ? job.getId() : ""));

			System.out
					.println(" Company Name "
							+ (job.getCompanyName() != null ? job
									.getCompanyName() : ""));

			System.out.println(" Posted By "
					+ (job.getPostedByFirstName() != null ? job
							.getPostedByFirstName() : "")
					+ " "
					+ (job.getPostedByLastName() != null ? job
							.getPostedByLastName() : ""));

			System.out.println(" Job Headline "
					+ (job.getHeadLine() != null ? job.getHeadLine() : ""));

			System.out.println(" Job Description "
					+ (job.getDescriptionSnippet() != null ? job
							.getDescriptionSnippet() : ""));

			System.out.println(" Job Location "
					+ (job.getLocationDescription() != null ? job
							.getLocationDescription() : ""));

		}

	}

	public static String getCharacterDataFromElement(Element e) {
		Node child = e.getFirstChild();
		if (child instanceof CharacterData) {
			CharacterData cd = (CharacterData) child;
			return cd.getData();
		}
		return "";
	}

}
